package ophiux.wechatpay.sdk.client;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ophiux.wechatpay.sdk.OphiuxWeChatPaySDKException;
import ophiux.wechatpay.sdk.base.OphiuxMedicalPayBaseRequest;
import ophiux.wechatpay.sdk.base.OphiuxMedicalPayResponse;
import ophiux.wechatpay.sdk.common.net.HttpsApiRequest;
import ophiux.wechatpay.sdk.common.net.INetApiRequest;
import ophiux.wechatpay.sdk.common.parse.IOphiuxApiParser;
import ophiux.wechatpay.sdk.common.parse.json.OphiuxApiJsonParser;
import ophiux.wechatpay.sdk.common.parse.table.OphiuxApiTableParser;
import ophiux.wechatpay.sdk.common.parse.xml.OphiuxApiXmlParser;
import ophiux.wechatpay.sdk.common.proxy.NetApiRequestProxy;
import ophiux.wechatpay.sdk.common.utils.StringUtil;
import ophiux.wechatpay.sdk.util.AesUtil;
import ophiux.wechatpay.sdk.util.SignUtils;

public class DefaultMedicalPayClient implements IMedicalPayClient {
	private static Logger logger = LoggerFactory.getLogger(DefaultMedicalPayClient.class);
	/**
	 * 应用 id
	 */
	public String appId = "1nl5nz3y";
	/**
	 * 商户号
	 */
	public String merchantNo = "4850335347";
	/**
	 * 签名key
	 */
	public String key = "35a81677e006338d2d48c23b72926d645a676b26";

	/** 返回格式 */
	private String format = "JSON";
	/** 请求地址 Y */
	private String serviceURL;

	public DefaultMedicalPayClient() {
	}

	/**
	 * 初始参数
	 * 
	 * @param appId      应用 idY
	 * @param merchantNo 商户号Y
	 * @param key        签名秘钥
	 * @param serviceURL 请求地址 Y
	 */
	public DefaultMedicalPayClient(String appId, String merchantNo, String key, String serviceURL) {
		this.appId = appId;
		this.merchantNo = merchantNo;
		this.key = key;
		this.serviceURL = serviceURL;
	}

	@Override
	public <T extends OphiuxMedicalPayResponse> T executor(OphiuxMedicalPayBaseRequest<T> _request)
			throws OphiuxWeChatPaySDKException {
		if(StringUtil.isEmpty(key)||key.length()!=40) {
			throw new OphiuxWeChatPaySDKException("key为空或者不足40位");
		}
		
		IOphiuxApiParser<T> parser = null;
		Class clzz = _request.getResponseClass();
		if (format.equals("XML")) {
			parser = new OphiuxApiXmlParser<T>(clzz);
		} else if (format.equals("TABLE")) {
			parser = new OphiuxApiTableParser<T>(clzz);
		} else if (format.equals("JSON")) {
			parser = new OphiuxApiJsonParser<T>(clzz);
		}
		T responseEntity = doSoapApiRequest(_request, parser);
		return responseEntity;
	}

	public <T extends OphiuxMedicalPayResponse> T doSoapApiRequest(OphiuxMedicalPayBaseRequest<T> _request,
			IOphiuxApiParser<T> parser) throws OphiuxWeChatPaySDKException {
		// 拼接请求参数
		String httpSoapParam = getHttpSoapParam(_request);
		System.out.println("医保支付请求参数：\n"+httpSoapParam);
		logger.info("医保支付请求参数：\n" + httpSoapParam);
		INetApiRequest netApiRequest = new HttpsApiRequest();
		NetApiRequestProxy netApiReqProxy = new NetApiRequestProxy(netApiRequest);
		// 发送请求
		String response = netApiReqProxy.request(serviceURL, _request.getApiMethod(), httpSoapParam, 30000);

		logger.info("医保支付返回参数：\n" + response );
		System.out.println("医保支付返回参数：\n" + response);
		T responseEntity = parser.parser(response);
		
		String result = AesUtil.decrypt(responseEntity.getData(),key.substring(8,40));
		T responseEntity2 = parser.parser(result);
		responseEntity2.setCode(responseEntity.getCode());
		responseEntity2.setData(result);
		responseEntity2.setMessage(responseEntity.getMessage());
		responseEntity2.setSuccess(responseEntity.isSuccess());
		
		responseEntity2.setRealResponseDataSource(response);
		responseEntity2.setRequestParam(httpSoapParam);
		return responseEntity2;
	}

	public String getHttpSoapParam(OphiuxMedicalPayBaseRequest _request) throws OphiuxWeChatPaySDKException {
		// 拼接 公有参数 map
		Map<String, String> publicParams = new HashMap<String, String>();
		publicParams.put("appId", appId);
		publicParams.put("merchantNo", merchantNo);
		publicParams.put("key",key);

		Map<String, String> requ = new HashMap<String, String>();
		requ.putAll(publicParams);
		// 获取业务参数
		Map<String, String> bParamXML = _request.getTextParam();
		requ.putAll(bParamXML);
		try {
			String sign = SignUtils.getSign(requ, key);
			publicParams.put("sign", sign);
		} catch (Exception e) {
			System.out.println("签名发生错误");
			e.printStackTrace();
		}

		// 将业务参数、共有参数转化为JSON
		String requestParamXML = _request.toRequestParam(publicParams, bParamXML);
		return requestParamXML;
	}

}
